Linux 管理記憶體時,常會區分 anonymous memory 和 file-backed memory。這個差異會影響 page fault 怎麼處理、memory reclaim 能不能回收、資料是否需要寫回磁碟,以及觀察工具裡的數字該怎麼解讀。
Anonymous memory 是沒有直接檔案來源的記憶體。heap、stack、malloc() 配置出來的大部分資料,都屬於這類。它們的內容是 process 執行期間產生的,不能靠重新讀某個檔案恢復。如果 kernel 想把 anonymous page 從 RAM 移走,通常需要把它寫到 swap,否則資料就會消失。
File-backed memory 則有檔案作為來源。最典型的例子是可執行檔、shared library,或藉由 mmap() 映射的檔案。對乾淨的 file-backed page 來說,kernel 如果需要回收 RAM,可以直接丟掉,因為之後需要時再從檔案讀回來就好。這也是 page cache 能被視為可回收記憶體的原因之一。
這裡的「乾淨」很重要。如果 file-backed page 被修改過,而且修改還沒寫回檔案,它就是 dirty page。dirty page 不能直接丟掉,必須先 writeback。這就是為什麼大量寫檔時,memory reclaim 可能牽涉 I/O,系統也可能因為 dirty page 太多而開始節流寫入。
Anonymous memory 和 file-backed memory 在 /proc/meminfo、smaps、top、free 的解讀上都很重要。看到記憶體被 page cache 用掉,不一定是壞事;看到 anonymous memory 持續成長,則比較可能代表 process 自己真的保留了越來越多資料。兩者對 reclaim 的代價不同,排查方向也不同。
container 場景裡,這個區分同樣重要。某個 container 可能因為讀大量檔案而累積 file cache,也可能因為程式資料結構成長而累積 anonymous memory。兩者都可能算進 cgroup memory usage,但回收難度和造成 OOM 的風險不一樣。
下一篇會看 demand paging。前面提過很多次「用到才配置」,接下來就把這個策略拆清楚:Linux 為什麼可以先答應 process 一段位址空間,卻不立刻付出完整的 RAM 成本。